package cn.honqun.tinycms.common.advice;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.honqun.tinycms.common.dto.ReturnObject;
import cn.honqun.tinycms.common.exce.ApplicationException;
import cn.honqun.tinycms.constants.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.security.auth.login.LoginException;
import java.util.Objects;

/**
 * <h1>全局异常处理</h1>
 * RestControllerAdvice: 组合注解, ControllerAdvice + ResponseBody, 是对 RestController 的功能增强
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ReturnObject exceptionHandler(Exception e) {
        e.printStackTrace();

        ReturnObject returnObject = ReturnObject.error();
        //处理后端验证失败产生的异常
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            returnObject.message(Objects.requireNonNull(exception.getBindingResult().getFieldError()).getDefaultMessage());
        }
        //处理业务异常
        else if (e instanceof ApplicationException) {
            ApplicationException exception = (ApplicationException) e;
            returnObject.message(exception.getMessage());
        }
        // 无此角色
        else if (e instanceof NotRoleException) {
            returnObject.message(SecurityConstants.ERROR_NOT_ROLE);
        }
        // 权限不足
        else if (e instanceof NotPermissionException) {
            returnObject.message(SecurityConstants.ERROR_NOT_PERMISSION);
        }
        // 未登录
        else if (e instanceof cn.dev33.satoken.exception.NotLoginException) {
            returnObject.message(SecurityConstants.ERROR_NOT_LOGIN);
        }
        // SaToken异常基类
        else if (e instanceof cn.dev33.satoken.exception.SaTokenException) {
            returnObject.message(SecurityConstants.ERROR_AUTH);
        }

        //处理其余的异常
        else {
            returnObject.message("系统错误，请稍后重试");
        }

        return returnObject;
    }

}
